import React, { useEffect, useRef, useState } from 'react';

import { PageContainer, PageContainerProps } from '@ant-design/pro-layout';
import { ActionType, ProTable, ProTableProps } from '@ant-design/pro-table';
import { IdEntity, IdType } from '@/types/base-type';
import { Button, Flex, Tooltip } from 'antd';
import { ClearOutlined } from '@ant-design/icons';
import { autoRc } from '@/utils/auto-render';
import { ToolBar, ToolBarProps } from '@/components/SuperTable/ToolBar';
import { ProFormInstance } from '@ant-design/pro-form';

declare type SelectedType<RecordType> = {
  rowKeys?: IdType[];
  rows?: RecordType[];
}

declare type SuperTableActionType<RecordType extends IdEntity<IdType>> =
  ActionType
  & ProFormInstance<RecordType>
  & {
  getSelectedRowKeys: () => IdType[];
  getSelectedRows: () => RecordType[];
};

declare type ToolBarRenderType<RecordType extends IdEntity<IdType>> = (action: ActionType | undefined, rows: {
  selectedRowKeys?: (string | number)[];
  selectedRows?: RecordType[];
}) => {
  actions: React.ReactNode[];
  type?: 'before' | 'after' | 'cover';
} & Omit<ToolBarProps<RecordType>, 'columns' | 'action' | 'rows' | 'tableRef'>;

declare type SuperTableProps<RecordType extends IdEntity<IdType>, SearchParameterType> =
  Omit<ProTableProps<RecordType, SearchParameterType>, 'actionRef' | 'formRef'>
  & {
  container?: PageContainerProps;
  instance?: {
    current: SuperTableActionType<RecordType>;
  };
  toolBarRenderMerge?: ToolBarRenderType<RecordType>;
}

const SuperTable = <RecordType extends IdEntity<IdType>, SearchParameterType = any>(props: SuperTableProps<RecordType, SearchParameterType>) => {
  const {
    instance,
    container,
    columns,
    toolBarRender,
    toolBarRenderMerge,
    rowSelection,
    pagination,
    scroll,
  } = props;

  const _defaultPageContainerProps: PageContainerProps = {
    title: false,
  };

  const actionRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance>();
  const selectedRef = useRef<SelectedType<RecordType>>();

  const [ tableRef, setTableRef ] = useState<SuperTableProps<RecordType, SearchParameterType>['instance']>();

  useEffect(() => {
    const ref = {
      current: {
        ... instance?.current,
        ... actionRef.current,
        ... formRef.current,
        getSelectedRows: () => selectedRef.current?.rows || [],
        getSelectedRowKeys: () => selectedRef.current?.rowKeys || [],
      },
    } as SuperTableProps<RecordType, SearchParameterType>['instance'];

    setTableRef(ref);

    if (instance) instance.current = ref?.current as any;
  }, []);

  return <PageContainer { ... _defaultPageContainerProps } { ... container }>
    <ProTable<RecordType>
      rowKey="id" columns={ columns }
      { ... props as any }
      actionRef={ actionRef } formRef={ formRef }
      scroll={ { x: true, ... scroll } }
      rowSelection={
        rowSelection === false ? false : {
          type: 'checkbox',
          ... rowSelection,
        }
      }
      toolBarRender={
        (action, rows) => {
          if (toolBarRender === false) {
            return false;
          } else if (typeof toolBarRender === 'function') {
            return toolBarRender(action, rows);
          } else if (typeof toolBarRenderMerge === 'function') {
            const nodes: React.ReactNode[] = [];
            const bar = toolBarRenderMerge(action, rows);
            const { type = 'after', actions } = bar;

            const defaultToolBar = <ToolBar<RecordType>
              { ... bar }
              tableRef={ tableRef } action={ action } rows={ rows } columns={ columns }
            />;

            if (type === 'before') {
              nodes.push(... actions, defaultToolBar);
            } else if (type === 'after') {
              nodes.push(defaultToolBar, ... actions);
            } else if (type === 'cover') {
              nodes.push(... actions);
            }

            return nodes;
          }

          return <ToolBar<RecordType>
            tableRef={ tableRef } action={ action } rows={ rows } columns={ columns }
          />;
        }
      }
      tableAlertOptionRender={
        ({ intl, selectedRowKeys, selectedRows }) => {
          selectedRef.current = {
            rowKeys: selectedRowKeys as any,
            rows: selectedRows as any,
          };

          return null;
        }
      }
      tableAlertRender={ false }
      pagination={
        pagination === false ? false : {
          ... pagination,
          showTotal: (totalValue, range) => {
            return <Flex gap="small">
              <div>已选择：<span> { autoRc.renderHighlightNumber(selectedRef.current?.rowKeys?.length || 0) } </span>条
              </div>
              <Tooltip title="清空已选择项">
                <Button
                  type="primary"
                  disabled={ (selectedRef.current?.rowKeys?.length || 0) <= 0 }
                  shape="circle" style={ { marginLeft: 8, marginRight: 8 } }
                  // @ts-ignore
                  onClick={ () => actionRef.current?.clearSelected() }
                  icon={ <ClearOutlined /> } size="small"
                />
              </Tooltip>
              <div>第 { range[0] }-{ range[1] } 条/总共 <span>{ totalValue }</span> 条</div>
            </Flex>;
          },
        }
      }
    />
  </PageContainer>;
};

SuperTable.useTableRef = <RecordType extends IdEntity<IdType> = any>(init?: Partial<SuperTableActionType<RecordType>>): {
  current: SuperTableActionType<RecordType>
} => {
  const ref = useRef<SuperTableActionType<RecordType>>(init as any);

  return { current: ref.current };
};

export {
  SuperTableProps, SuperTable, SuperTableActionType,
};